/**
 * 用户控制器模块
 * controller\user.js
 *
 * 说明：
 * 中间件处理路由请求：
 * 1. req.params --> 路由参数 /:id  -> req.params.id
 * 2. req.query  --> url查询串  ?k1=v1&k2=v2  -> req.query.k1, req.query.k2
 * 3. req.body   --> 数据对象  {k1:v1, k2:v2} -> req.body.k1, req.body.k2
 *
 * 中间件进行异步封装（async/await），不会直接执行，需要进行函数立即执行的方式。
 */
 
const express = require("express");
 
const util = require("../common/util");

//访问user数据模型
/**
 * @typedef {UserDB}
 */
const UserDB = require("../model/sqlite/user");



/**
 * 获取用户信息
 * @param {express.Request} req 请求
 * @param {express.Response} res 响应
 */
function find(req,res){
    // 异步函数会自动返回一个 Promise 对象.自动调用函数
    (async function(){
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.find(req.params.id);
        // await db.close()
        // %O输出一个对象
        util.logFormat(`获取【${req.params.id}】用户信息${Date.now()}%O`,result);
        res.json(util.FormatJSONData(200,`获取用户信息【${req.params.id}】`,result));
    })();
}

/**
 * 获取用户信息列表
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function findAll(req,res){
    (async function(){
        //1.处理输入的数据
        //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        //2. 访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.findAll(limit, offset);
        //await db.close();

        //输出数据
        // %O输出一个对象
        util.logFormat(`获取【limit=${limit}&offset=${offset}】用户信息%O`,result);
        res.json(util.FormatJSONData(200,`获取用户信息列表`,result));
    })();
}
/**
 * 新增用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function add(req,res){
    (async function(){
        let user = {
            //FIXME:req.body的数据安全性校验
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
            role: req.body.role,
            lastLoginTime: 0,
            lastLoginIP: "never login",
            createdTime: Date.now(),
            createdIP: util.getReqRemoteIP(req),
            updatedTime: Date.now(),
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.add(user);

        //await db.close();

        //输出数据
        util.logFormat(`新增用户信息：lastId->${result}`);
        res.json(util.FormatJSONData(201,`新增用户信息`, { lastID: result }));
    })();
}
/**
 * 更新用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function update(req,res){
    (async function(){
        let user = {
            //FIXME:req.body的数据安全性校验
            id: req.params.id,
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
            role: req.body.role,
            updatedTime: Date.now(),
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.update(user);

        //await db.close();

        //输出数据
        util.logFormat(`修改用户信息：lastId->${result}`);
        res.json(util.FormatJSONData(201,`修改用户信息`, { change: result }));
    })();
}
/**
 * 删除用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function remove(req,res){
    (async function(){

        let userId = req.params.id;
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.remove(userId)

        util.logFormat(`删除【${userId}】用户信息%O`,result);
        res.json(util.FormatJSONData(200,`删除用户信息【${userId}】`,result));
    })();
}

/**
 * 获取用户总数
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function getCount(req, res) {
    (async function () {
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.getCount();
        //await db.close();
        util.log(`获取用户总数：${result}`);
        res.json(util.FormatJSONData(200, `获取用户总数息`, result));
    })();
   }

/**
 * 按关键搜索用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function search(req, res) {
    (async function () {
        //1.处理输入的数据
        //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
        let q = req.query.q;
        let limit = req.query.limit ? req.query.limit : -1;
        let offset = req.query.offset ? req.query.offset : -1;
        //2. 访问数据
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.search(q, limit, offset);
        //await db.close();
        
        //3.输出数据
        util.logFormat(`获取关键字为【${q}】【limit=${limit}&offset=${offset}】用户信息%O`, result);
        res.json(util.FormatJSONData(200, `获取指定关键字的用户信息列表`, result));
    })();
   }
   

/**
 * 注册用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function register(req,res){
    (async function(){
        let user = {
            //FIXME:req.body的数据安全性校验
            username: req.body.username,
            password: util.md5pwd(req.body.password),
            nickname: req.body.nickname ? req.body.nickname:"",
            truename: req.body.truename ? req.body.truename:"",
            avatar: req.body.avatar ? req.body.avatar:"",
            role:2,
            lastLoginTime: 0,
            lastLoginIP: "never login",
            createdTime: Date.now(),
            createdIP: util.getReqRemoteIP(req),
            updatedTime: Date.now(),
        };
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.add(user);

        //await db.close();

        //输出数据
        util.logFormat(`注册用户信息：lastId->${result}`);
        res.json(util.FormatJSONData(201,`注册用户信息`, { lastID: result }));
    })().catch(err=>{
        util.err(err);
        res.json(util.FormatJSONData(500, "服务器内部错误", {Error: err}));
    });
}
/**
 * 用户登录
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function login(req,res){
    (async function () {
        //FIXME:req.body的数据安全性校验
        let username = req.body.username;
        let password = util.md5pwd(req.body.password);
                
        let msg = `用户【${username}】登录失败，请检查用户名和密码`;
        let data = { loginStatus: "failed" };
                
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.login(username, password);
                
        if (result) {
            msg = `用户【${username}】登录成功`;
            data = {
                loginStatus: "success",
                userId: result.id,
                username: result.username,
                nickname: result.nickname,
                truename: result.truename,
                role: result.role,
            };
            let lastLogin = {
                time: Date.now(),
                ip: util.getReqRemoteIP(req),
            };
            await db.touch(username, lastLogin);
            //使用session保存登录状态
            req.session.isLogin = true;
            req.session.user = result;
            // return 1
        }
        //await db.close();
        util.logFormat(`用户【${username}】登录，用户信息%O`, result);
        res.json(util.FormatJSONData(200, msg, data));
    })();
}
/**
 * 用户退出
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function logout(req,res){
    if (req.session.user) {
        let username = req.session.user.username;
        req.session.destroy((err) => util.log(err));
        
        util.log(`用户【${username}】退出，用户session值【${req.session}】`);
        res.json(
            util.FormatJSONData(200, `用户【${username}】退出系统`, {
                logoutStatus: "success",
            })
        );
        }else{
        res.json(util.FormatJSONData(200, `非正确访问路径`));
        }
    }

    /**
 * 修改个人信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function changeInfo(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let info = {
            nickname: req.body.nickname,
            truename: req.body.truename,
            avatar: req.body.avatar,
        };
        let id = req.session.user.id;
    
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changeInfo(id, info);
        //await db.close();
        util.log(`修改个人信息：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人信息成功`, { changes: result }));
    })();
}

/**
 * 修改用户密码
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function changePassword(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd(req.body.password);
        let id = req.session.user.id;
        
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        //await db.close();
        util.log(`修改用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `修改个人密码成功`, { changes: result }));
     })();
   }
    
   /**
    * 重置用户密码
    * @param {express.Request} req  请求
    * @param {express.Response} res  响应
    */
   function resetPassword(req, res) {
    (async function () {
        //FIXME:req.body的数据安全性校验
        let password = util.md5pwd("123456");
        let id = req.params.id;
        
        let db = UserDB.getInstance();
        await db.connect();
        let result = await db.changePassword(id, password);
        //await db.close();
        util.log(`重置用户密码：changes->${result}`);
        res.json(util.FormatJSONData(200, `用户密码重置成功`, { changes: result }));
     })();
   }

module.exports = {
    find,
    findAll,
    add,
    update,
    remove,
    register,
    getCount,
    login,
    logout,
    search,
    changeInfo,
    changePassword,
    resetPassword
}